package com.knife.oauth.util;


import com.knife.common.constants.BaseConstants;
import com.knife.oauth.domain.entity.KnifeUserDetails;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collections;

/**
 * @author HQK
 */
public class DetailHelper {

    private static final KnifeUserDetails ANONYMOUS = new KnifeUserDetails("ANONYMOUS","known", Collections.emptyList());

    public static KnifeUserDetails getAnonymousDetails() {
        return ANONYMOUS;
    }

    public static KnifeUserDetails getUserDetails() {
        if (SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null) {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if (principal instanceof KnifeUserDetails) {
                return (KnifeUserDetails) principal;
            } else {
//                Object details = SecurityContextHolder.getContext().getAuthentication().getDetails();
//                if (details instanceof OAuth2AuthenticationDetails) {
//                    Object decodedDetails = ((OAuth2AuthenticationDetails)details).getDecodedDetails();
//                    if (decodedDetails instanceof KnifeUserDetails) {
//                        return (KnifeUserDetails)decodedDetails;
//                    }
//                }
                return null;
            }
        } else {
            return null;
        }
    }

    public static KnifeUserDetails getClientDetails() {
        if (SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null) {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if (principal instanceof KnifeUserDetails) {
                return (KnifeUserDetails)principal;
            } else {
//                Object details = SecurityContextHolder.getContext().getAuthentication().getDetails();
//                if (details instanceof OAuth2AuthenticationDetails) {
//                    Object decodedDetails = ((OAuth2AuthenticationDetails)details).getDecodedDetails();
//                    if (decodedDetails instanceof KnifeUserDetails) {
//                        return (KnifeUserDetails)decodedDetails;
//                    }
//                }
                return null;
            }
        } else {
            return null;
        }
    }

    public static void setKnifeUserDetails(KnifeUserDetails customUserDetails) {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        if (securityContext != null) {
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(customUserDetails, customUserDetails.getPassword());
            securityContext.setAuthentication(usernamePasswordAuthenticationToken);
        }
    }


    public static void setUserDetails(UserDetails customUserDetails) {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        if (securityContext != null) {
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(customUserDetails, customUserDetails.getPassword());
            securityContext.setAuthentication(usernamePasswordAuthenticationToken);
        }
    }

    public static void clear(){
        SecurityContextHolder.clearContext();
    }

    static {
        ANONYMOUS.setUserId(BaseConstants.ANONYMOUS_USER_ID);
        ANONYMOUS.setOrganizationId(BaseConstants.DEFAULT_TENANT_ID);
        ANONYMOUS.setTenantId(BaseConstants.DEFAULT_TENANT_ID);
        ANONYMOUS.setTenantIds(Collections.singletonList(BaseConstants.DEFAULT_TENANT_ID));
        ANONYMOUS.setLanguage(BaseConstants.DEFAULT_LOCALE_STR);
        ANONYMOUS.setTimeZone("GMT+8");
    }

}
